package com.demo.sender.totp.twilio;

import com.demo.common.ResultData;
import com.demo.filter.RequestContextHelper;
import com.twilio.rest.verify.v2.service.Verification;
import com.twilio.rest.verify.v2.service.VerificationCheck;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @author wangfengchen
 */
@Component
@Slf4j
public class TwilioTotpSender {


  @Autowired
  private TwilioConfig twilioConfig;


  /**
   * 发送验证码，<a href="https://www.twilio.com/docs/verify/api">https://www.twilio.com/docs/verify/api</a>
   */
  public ResultData<Object> send(String phone, String countryCode) {
    String requestId = RequestContextHelper.get().getRequestId();
    Verification verification = null;
    try {
      verification = Verification.creator(twilioConfig.getServiceId(), addPrefix(phone, countryCode), Verification.Channel.SMS.toString()).create();
    } catch (Exception e) {
      log.error("requestId = {}，exception = {}", requestId, ExceptionUtils.getStackTrace(e));
      return ResultData.fail("手机号或国家码有误");
    }
    return ResultData.success(verification);
  }

  /**
   * 校验验证码
   */
  public ResultData<Object> verify(String phone, String countryCode, String code) {
    String requestId = RequestContextHelper.get().getRequestId();
    VerificationCheck verificationCheck = null;
    try {
      verificationCheck = VerificationCheck.creator(twilioConfig.getServiceId()).setTo(addPrefix(phone, countryCode)).setCode(code).create();
    } catch (Exception e) {
      log.error("requestId = {}，exception = {}", requestId, ExceptionUtils.getStackTrace(e));
      return ResultData.fail("验证码已过期");
    }
    return ResultData.success(verificationCheck);
  }

  /**
   * 查询验证状态，参数为发送验证码返回的sid，<a href="https://www.twilio.com/docs/verify/api/verification">https://www.twilio.com/docs/verify/api/verification</a>
   */
  public ResultData<Object> getStatus(String sid) {
    Verification verification = null;
    try {
      verification = Verification.fetcher(twilioConfig.getServiceId(), sid).fetch();
    } catch (Exception e) {
      log.error("exception = {}", ExceptionUtils.getStackTrace(e));
      return ResultData.fail("验证码已过期");
    }
    return ResultData.success(verification);
  }

  /**
   * 修改验证状态，参数可以是手机号也可以是发送验证码后返回的sid
   */
  public ResultData<Object> updateStatus(String sid) {
    Verification verification = null;
    try {
      verification = Verification.updater(twilioConfig.getServiceId(), sid, Verification.Status.APPROVED).update();
    } catch (Exception e) {
      log.error("exception = {}", ExceptionUtils.getStackTrace(e));
      return ResultData.fail("验证码已过期");
    }
    return ResultData.success(verification);
  }

  /**
   * 取消验证码，参数可以是手机号也可以是发送验证码后返回的sid
   */
  public ResultData<Object> cancelVerify(String sid) {
    Verification verification = null;
    try {
      verification = Verification.updater(twilioConfig.getServiceId(), sid, Verification.Status.CANCELED).update();
    } catch (Exception e) {
      log.error("exception = {}", ExceptionUtils.getStackTrace(e));
      return ResultData.fail("验证码已过期");
    }
    return ResultData.success(verification);
  }

  /**
   * 添加前缀
   *
   * @param phone
   * @return
   */
  private String addPrefix(String phone, String countryCode) {
    if (!StringUtils.startsWith(phone, "+")) {
      phone = "+" + countryCode.replaceFirst("00", "") + phone;
    }
    return phone;
  }


}
